/**
 * Advanced Software Engineering (Monica Farrow)
 * ProcessingController class
 * 
 * Some of the methods in this class have been based on lecture notes provided by
 * Monica Farrow as a part of Software Engineering courses at Heriot-Watt University.
 */

package depotControllers;

import depot.*;
import depotAdmin.*;
import depotModels.*;
import depotViews.ProcessingGUI;

/**
 * ProcessingController class - mainly controls the CustomerProcessing model
 * and also interacts with the CustomerQueue model
 * @author Ionut Iordache, Nikky Afunugo, Dave Bond
 */
public class ProcessingController implements Runnable {

	private ProcessingGUI view; // allows controller to respond to ActionEvents in GUI
	private CustomerProcessing model;   // stores processed customers
	private CustomerQueue model2;        // stores customer queue

	/**
	 * constructor for ProcessingController
	 * registers model and view
	 * @param view    the ProcessingGUI object
	 * @param model   the CustomerProcessing object
	 * @param model2  the CustomerQueue object
	 */
	public ProcessingController(ProcessingGUI view, CustomerProcessing model, CustomerQueue model2) {
		this.model = model;
		this.model2 = model2;		
		this.view = view;

	}

	/**
	 * run method - does all the work
	 * oversees the processing of the CustomerQueue
	 */
	public void run() {

		// process customers in the queue
		processQueue();

		// indicate queue processing finished
		model2.setProcFinishedFlag();

		// produce 'processed customers' part of final report
		String finalReport = model.compileReport();
		model.writeToLog("report.txt",finalReport,"report 2");

	}

	/**
	 * processQueue method
	 * calculates fee, removes customer from custQueue
	 * and places in processedCustomers for production of final report
	 */
	public void processQueue() {

		while (! DepotUtils.getEndOfDay()) {
			// get first customer in queue
			Customer cust = model2.getFirst();
			if (cust != null) {

				// remove customer from custQueue
				model2.removeFromQueue(cust, DepotUtils.getProcLoopFinished());

				// add customer to processedCustomers
				model.addCustomer(cust);

				try { // delay to make visible in GUI 

					// implement random delay based on current speed value
					long baseDelay = DepotUtils.getProcSpeed();
					// generate random modifier between 0.5 & 1.5
					Double randModifier = DepotUtils.getRandomDouble(0.5, 1.5);
					// apply modifier to base value and convert back to long
					Double convertedBase = baseDelay * randModifier;
					long thisDelay = convertedBase.longValue();

					Thread.sleep(thisDelay);

				} catch (InterruptedException e) {
				} 

			}
			else { // if queue empty exit from loop
				model2.setCustInQueue(false);
			}
		}
		model.notifyObservers("end");
	}


}
